package vipercfg

import (
	"fmt"
	"huijing_mall/shared/common"
	"huijing_mall/shared/kernel/hmErrors"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"

	"huijing_mall/pkg/logger"
)

func ViperInit(env string) *RedaViper {
	if env == "" {
		env = "dev"
	}

	// 初始化viper
	viper.SetConfigName(env)
	viper.SetConfigType("yaml")

	// 设置配置搜索路径
	pwd, _ := os.Getwd()
	logger.Info(pwd)
	if strings.Contains(pwd, "/cmd/app") { //liunx 电脑不一样
		pwd = strings.ReplaceAll(pwd, "/cmd/app", "")
	}
	configPaths := []string{
		filepath.Join(pwd, "configs"),
		filepath.Join(pwd, "backend", "configs"),
	}

	for _, path := range configPaths {
		viper.AddConfigPath(path)
	}

	// 设置默认值
	setDefaults(env)

	// 读取配置
	if err := viper.ReadInConfig(); err != nil {
		handleConfigError(err, env, configPaths)
	}

	// 解析配置
	config := &RedaViper{}
	if err := viper.Unmarshal(config); err != nil {
		panic(hmErrors.ErrSystem(common.StrPinJie("Data unmarshal error: ", err.Error())))
	}

	// 设置配置热重载
	setupConfigReload(config)

	logger.Info("Viper init success for environment: ", env)
	return config
}

func setDefaults(env string) {
	viper.SetDefault("app.env", env)
	viper.SetDefault("server.port", 8080)
	// 其他默认值...
}

func handleConfigError(err error, env string, paths []string) {
	if _, ok := err.(viper.ConfigFileNotFoundError); ok {
		panic(hmErrors.ErrSystem(fmt.Sprintf(
			"Config file %s.yaml not found in paths: %v",
			env,
			paths,
		)))
	}
	panic(hmErrors.ErrSystem(fmt.Sprintf(
		"Error reading vipercfg: %v. Searched in: %v",
		err,
		paths,
	)))
}

func setupConfigReload(config *RedaViper) {
	var mutex sync.RWMutex

	viper.WatchConfig()
	viper.OnConfigChange(func(e fsnotify.Event) {
		logger.Info("Config file changed:", e.Name)

		mutex.Lock()
		defer mutex.Unlock()

		if err := viper.Unmarshal(config); err != nil {
			logger.Error("Error reloading vipercfg: %v", err)
			return
		}
		logger.Info("Config reloaded successfully")
	})
}

type RedaViper struct {
	Env       string          `mapstructure:"Env"`
	Database  DatabaseConfig  `mapstructure:"DatabaseConfig"`
	CacheBase CacheBaseConfig `mapstructure:"CacheBaseConfig"`
	RabbitMQ  RabbitMQConfig  `mapstructure:"RabbitMQConfig"`
	//PwdKey     string          `mapstructure:"PwdKey"`//暂时不使用这个字段
	ServerHost string `mapstructure:"ServerHost"`
	ServerPort string `mapstructure:"ServerPort"`
}

type DatabaseConfig struct {
	Name     string `mapstructure:"Name"`
	Pwd      string `mapstructure:"Pwd"`
	Host     string `mapstructure:"Host"`
	Port     int    `mapstructure:"Port"`
	Database string `mapstructure:"Database"`
	Charset  string `mapstructire:"Charset"`
}

type CacheBaseConfig struct {
	Pwd  string `mapstructure:"Pwd"`
	Host string `mapstructure:"Host"`
	Port int    `mapstructure:"Port"`
}

// RabbitMQConfig 连接配置
type RabbitMQConfig struct {
	URL        string `mapstructure:"URL"`        // 连接地址，例如: amqp://user:pass@host:port/vhost
	Durable    bool   `mapstructure:"Durable"`    // 队列是否持久化
	AutoDelete bool   `mapstructure:"AutoDelete"` // 队列是否自动删除
	Exclusive  bool   `mapstructure:"Exclusive"`  // 是否排他队列
	NoWait     bool   `mapstructure:"NoWait"`     // 是否非阻塞
}
